Settings 'Start' and 'End' Dates in a Calendar Control

Description

A common use of a calendar control, particularly on travel sites, is to have users enter a 'start' and 'end' date into the calendar, or an 'arrival' and 'departure' date. It is desirable to be able to prevent the user from being able to enter an 'end' date that is before their 'start' date or even the current date. Fortunately this is fairly easy to accomplish in Alpha Anywhere.

images/se23.png
The departure calendar on the left sets the low date for the return calendar on the right.

For a visual explanation on how to do this watch this two part video Part 1, Part 2, or read the guide below.

Create Two Calendar Controls and a HTML Free Form Control

  1. In the UX Builder on the UX Controls page open the 'Data Controls' menu. Click on the [Calendar] control option to add a calendar control to the component. Give the calendar control the name 'dstart' and the label 'Departure Date'.

    images/se2.png
  2. Highlight the Calendar control. In the properties list on the right. Scroll down to the 'Date/Time Picker Properties'. Click the [...] button next to the 'Low Date' property.

    images/se3.png
  3. In the 'Property Value' box select the 'Javascript function' radio button. In the Javascript function name textbox add the following function name and click OK:

    setLowDateForDStart
    images/se4.png
  4. Check the 'Draw boxes around dates' property checkbox.

    images/se5.png
  5. Check the 'Has events' property checkbox, then click the '+' button next to it to expand the list of events.

    images/se6.png
  6. Next to the 'onSelect' event add the following function name:

    setLowDateForDend
    images/se7.png
    This is the function that will be called whenever a start date is selected in the [dstart] calendar control.
  7. Click on the [Calendar] option again to add a second calendar control to the component. Give the new control the name 'dend' and the label 'Return Date'.

    images/se8.png
  8. Highlight the [dend] calendar in the controls tree. In the properties list on the right check the 'Draw boxes around dates' checkbox in the 'Date/Time Picker Properties' section.

    images/se9.png

Define the Low Date Functions

  1. Expand the 'Code' menu and click on the 'Javascript functions' page.

    images/se10.png
  2. Add the following javascript to create a setLowDateForDend() function.

    function setLowDateForDend() {
    var curDate = {dialog.object}.getValue('DSTART');
    var d2 = {dialog.object}.getControl('DEND');
    d2.datePicker.disabledDates.low = curDate;
    
    var curEndDate = {dialog.object}.getValue('DEND');
    var dtFormat = {dialog.object}.stateInfo.__dtfmt;
    var curEndDate2 = new Date();
    curEndDate2.fromFormat(curEndDate,dtFormat);
    
    var curDate2 = new Date()
    curDate2.fromFormat(curDate,dtFormat);
    if (curDate2 > curEndDate2 ) {
         {dialog.object}.setValue('DEND',curDate);
    }
    d2.refresh();
    
    }
    images/se11.png
  3. Underneath the first function add a second function definition for the setLowDateForDStart() function using the following code.

    function setLowDateForDStart() {
    	return new Date();
    }
    images/se12.png

About setLowDateForDend() and setLowDateForDStart()

Inside the setLowDateForDend() function definition the getValue method is the first thing to be called. This method gets the value of the start date calendar, [dstart], and assigns that value to a variable named 'curDate'. The getControl() method is then used to to get a pointer to the control for the date-end calendar, [dend]. This pointer is assigned to the javascript variable 'd2'.

var curDate = {dialog.object}.getValue('DSTART');
var d2 = {dialog.object}.getControl('DEND');

The next line of code sets the low date of the second calendar, making it equal to the date that was selected in the first calendar control, 'curDate'. As soon as there is a pointer to the second calendar control, 'd2', it is possible to do this. Defining the low date in this way will make it impossible for users to select a return date before their selected departure date; because it will disable all of the days before the selected departure date on the second calendar control.

d2.datePicker.disabledDates.low = curDate;

The getValue() method is used again in order to get the value of the [dend] calendar by reading the date-end field. This value is assigned o the variable 'curEndDate'. The date format that is stored in the dialog object is then read by referencing the ux component's state info. This specifies what format is being used for all date values via the 'Date format' field in the UX Properties. For example, the date format "MM/dd/yyyy"", could be used. Assigning the date format to a javascript variable allows all callbacks to read from the same date format easily.

var curEndDate = {dialog.object}.getValue('DEND');
var dtFormat = {dialog.object}.stateInfo.__dtfmt;

The Date() function is used to create a new date object, that is assigned to the variable 'curEndDate2'. This is the built-in javascript date method. This variable is used to get the value that was read out of the calendar for the end date, 'curEndDate', and then put it into a proper Javascript date object. At this point 'curEndDate' only represents a javascript string, not a date object. The fromFormat() method is used to actually get a date object from the string. This method takes as arguments the date string, 'curEndDate', and the date format, 'dtFormat'.

var curEndDate2 = new Date();
curEndDate2.fromFormat(curEndDate,dtFormat);

The Date() Method is called a second time and assigned to a variable named 'curDate2'. This is used to create a second date object for the current date, i.e. the departure date.

var curDate2 = new Date()
curDate2.fromFormat(curDate,dtFormat);

The if statement states that if the departure date is greater than the return date, the value of the return date should be set to the departure date.

if (curDate2 > curEndDate2 ) {
     {dialog.object}.setValue('DEND',curDate);
}

The refresh() method is then called to refresh the second calendar.

d2.refresh();

The setLowDateForDStart() function simply returns a value that is the current date. This function is used in the [dstart] calendar in order to prevent users from selecting a date before the current date, i.e. today. This function is called from the [dstart] calendar in the function's 'Low date' property on the UX Controls page, in the 'Date/Time Picker Properties' section of the properties list.

Display the Time Between Two Selected Dates

  1. On the UX Controls page, open the 'Containers' menu and click on the [Free-form Layout] option to add a free-form layout to the control.

    images/se13.png
  2. Highlight the [Free-form Container] in the controls tree. In the properties list on the right click the [...] button next to the 'Free-form layout' property in the 'Free-form HTML' section.

    images/se14.png
  3. Add the following html to the free-form container.

    <p id="msg" style="display:none;">
    Trip duration is from <span id="t1" style="font-weight:bold;"></span> to 
    <span id="t2" style="font-weight:bold;"></span>
    </p>
    images/se15.png
  4. Highlight the [dend] calendar control in the controls tree.

    images/se16.png
  5. In the calendar's properties list on the right scroll down to the 'Date/Time Picker Properties' section. Check the 'Has events' checkbox.

    images/se17.png
  6. Click the '+' button next to the 'Has Events' property to expand the events list. Next to the 'onSelect' event type 'showMessage'.

    images/se18.png
  7. In the Code menu click to open the 'Javascript functions' page.

    images/se19.png
  8. In the setLowDateForDend() function definition add a showMessage() function call, just after the d2.refresh() function call.

    showMessage();
    images/se20.png
  9. The setLowDateForDend() function should now look like this:

    function setLowDateForDend() {
    var curDate = {dialog.object}.getValue('DSTART');
    var d2 = {dialog.object}.getControl('DEND');
    d2.datePicker.disabledDates.low = curDate;
    
    var curEndDate = {dialog.object}.getValue('DEND');
    var dtFormat = {dialog.object}.stateInfo.__dtfmt;
    var curEndDate2 = new Date();
    curEndDate2.fromFormat(curEndDate,dtFormat);
    
    var curDate2 = new Date()
    curDate2.fromFormat(curDate,dtFormat);
    if (curDate2 > curEndDate2 ) {
         {dialog.object}.setValue('DEND',curDate);
    }
    d2.refresh();
    showMessage();
    }
    images/se21.png
  10. At the end of the Javascript functions page add the following definition for the showMessage() function.

    function showMessage() {
    	$('msg').style.display = '';
    	var d1 = {dialog.object}.getValue('DSTART');
    	var d2 = {dialog.object}.getValue('DEND');
    	$('t1').innerHTML = d1;
    	$('t2').innerHTML = d2;
    }
    images/se22.png
    This code shows the trip duration.
  11. Run the component in Live Preview. Select a departure date. The dates before the current date should not be selectable. The dates before the selected departure date should also appear disabled on the return calendar.

    images/se23.png
  12. Select a return date in the return calendar. The trip duration should be displayed under the calendars.

    images/se24.png